/// 手环数据模型
/// 基于手环SDK的数据结构定义

import 'package:json_annotation/json_annotation.dart';

part 'ring_data_models.g.dart';

/// 步数信息模型
@JsonSerializable()
class RingStepsInfo {
  final int steps;
  final int distance;
  final int calories;
  final int time;
  final List<int>? hourlySteps; // 每半小时的步数数据，48个数据点

  const RingStepsInfo({
    required this.steps,
    required this.distance,
    required this.calories,
    required this.time,
    this.hourlySteps,
  });

  factory RingStepsInfo.fromJson(Map<String, dynamic> json) => _$RingStepsInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingStepsInfoToJson(this);
  
  factory RingStepsInfo.fromMap(Map<String, dynamic> map) {
    List<int>? hourlyData;
    if (map['stepsList'] != null) {
      hourlyData = List<int>.from(map['stepsList']);
    }
    
    return RingStepsInfo(
      steps: map['steps'] ?? 0,
      distance: map['distance'] ?? 0,
      calories: map['calories'] ?? 0,
      time: map['time'] ?? 0,
      hourlySteps: hourlyData,
    );
  }

  @override
  String toString() {
    return 'RingStepsInfo{steps=$steps, distance=$distance, calories=$calories, time=$time, hourlySteps=${hourlySteps?.length ?? 0} entries}';
  }
}

/// 睡眠信息模型
@JsonSerializable()
class RingSleepInfo {
  final int totalTime;
  final int deepTime;
  final int lightTime;
  final int awakeTime;
  final int remTime;
  final List<SleepDetailBean> details;

  const RingSleepInfo({
    required this.totalTime,
    required this.deepTime,
    required this.lightTime,
    required this.awakeTime,
    required this.remTime,
    required this.details,
  });

  factory RingSleepInfo.fromJson(Map<String, dynamic> json) => _$RingSleepInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingSleepInfoToJson(this);
  
  factory RingSleepInfo.fromMap(Map<String, dynamic> map) {
    List<SleepDetailBean> detailsList = [];
    if (map['details'] != null) {
      detailsList = (map['details'] as List)
          .map((detail) => SleepDetailBean.fromMap(detail))
          .toList();
    }

    return RingSleepInfo(
      totalTime: map['totalTime'] ?? 0,
      deepTime: map['deepTime'] ?? 0,
      lightTime: map['lightTime'] ?? 0,
      awakeTime: map['awakeTime'] ?? 0,
      remTime: map['remTime'] ?? 0,
      details: detailsList,
    );
  }

  @override
  String toString() {
    return 'RingSleepInfo{totalTime=$totalTime, deepTime=$deepTime, lightTime=$lightTime, awakeTime=$awakeTime, remTime=$remTime, details=${details.length} entries}';
  }
}

/// 睡眠详情模型
@JsonSerializable()
class SleepDetailBean {
  final int startTime;
  final int endTime;
  final int totalTime;
  final int type; // 0:清醒, 1:浅睡眠, 2:深睡眠, 3:REM睡眠

  const SleepDetailBean({
    required this.startTime,
    required this.endTime,
    required this.totalTime,
    required this.type,
  });

  factory SleepDetailBean.fromJson(Map<String, dynamic> json) => _$SleepDetailBeanFromJson(json);
  
  Map<String, dynamic> toJson() => _$SleepDetailBeanToJson(this);
  
  factory SleepDetailBean.fromMap(Map<String, dynamic> map) {
    return SleepDetailBean(
      startTime: map['startTime'] ?? 0,
      endTime: map['endTime'] ?? 0,
      totalTime: map['totalTime'] ?? 0,
      type: map['type'] ?? 0,
    );
  }

  String get typeName {
    switch (type) {
      case 0:
        return '清醒';
      case 1:
        return '浅睡眠';
      case 2:
        return '深睡眠';
      case 3:
        return 'REM睡眠';
      default:
        return '未知';
    }
  }

  @override
  String toString() {
    return 'SleepDetailBean{startTime=$startTime, endTime=$endTime, totalTime=$totalTime, type=$typeName}';
  }
}

/// 心率信息模型
@JsonSerializable()
class RingHeartRateInfo {
  final int startTime;
  final List<int> heartRateList;
  final int timeInterval; // 测量间隔（分钟）
  final String historyDay;

  const RingHeartRateInfo({
    required this.startTime,
    required this.heartRateList,
    required this.timeInterval,
    required this.historyDay,
  });

  factory RingHeartRateInfo.fromJson(Map<String, dynamic> json) => _$RingHeartRateInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingHeartRateInfoToJson(this);
  
  factory RingHeartRateInfo.fromMap(Map<String, dynamic> map) {
    return RingHeartRateInfo(
      startTime: map['startTime'] ?? 0,
      heartRateList: List<int>.from(map['heartRateList'] ?? []),
      timeInterval: map['timeInterval'] ?? 5,
      historyDay: map['historyDay'] ?? 'TODAY',
    );
  }

  @override
  String toString() {
    return 'RingHeartRateInfo{startTime=$startTime, heartRateList=${heartRateList.length} entries, timeInterval=$timeInterval, historyDay=$historyDay}';
  }
}

/// 血氧信息模型
@JsonSerializable()
class RingBloodOxygenInfo {
  final String historyDay;
  final List<int> list;
  final int? interval; // 测量间隔（小时）

  const RingBloodOxygenInfo({
    required this.historyDay,
    required this.list,
    this.interval,
  });

  factory RingBloodOxygenInfo.fromJson(Map<String, dynamic> json) => _$RingBloodOxygenInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingBloodOxygenInfoToJson(this);
  
  factory RingBloodOxygenInfo.fromMap(Map<String, dynamic> map) {
    return RingBloodOxygenInfo(
      historyDay: map['historyDay'] ?? 'TODAY',
      list: List<int>.from(map['list'] ?? []),
      interval: map['interval'],
    );
  }

  @override
  String toString() {
    return 'RingBloodOxygenInfo{historyDay=$historyDay, list=${list.length} entries, interval=$interval}';
  }
}

/// 温度信息模型
@JsonSerializable()
class RingTempInfo {
  final String historyDay;
  final List<double> tempList;

  const RingTempInfo({
    required this.historyDay,
    required this.tempList,
  });

  factory RingTempInfo.fromJson(Map<String, dynamic> json) => _$RingTempInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingTempInfoToJson(this);
  
  factory RingTempInfo.fromMap(Map<String, dynamic> map) {
    List<double> tempData = [];
    if (map['tempList'] != null) {
      tempData = (map['tempList'] as List)
          .map((temp) => (temp is int) ? temp.toDouble() : (temp is double ? temp : 0.0))
          .toList();
    }

    return RingTempInfo(
      historyDay: map['historyDay'] ?? 'TODAY',
      tempList: tempData,
    );
  }

  @override
  String toString() {
    return 'RingTempInfo{historyDay=$historyDay, tempList=${tempList.length} entries}';
  }
}

/// 心率变异性信息模型
@JsonSerializable()
class RingHrvInfo {
  final String historyDay;
  final List<int> hrvList;

  const RingHrvInfo({
    required this.historyDay,
    required this.hrvList,
  });

  factory RingHrvInfo.fromJson(Map<String, dynamic> json) => _$RingHrvInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingHrvInfoToJson(this);
  
  factory RingHrvInfo.fromMap(Map<String, dynamic> map) {
    return RingHrvInfo(
      historyDay: map['historyDay'] ?? 'TODAY',
      hrvList: List<int>.from(map['hrvList'] ?? []),
    );
  }

  @override
  String toString() {
    return 'RingHrvInfo{historyDay=$historyDay, hrvList=${hrvList.length} entries}';
  }
}

/// 压力信息模型
@JsonSerializable()
class RingStressInfo {
  final int stressLevel; // 0-100的压力值

  const RingStressInfo({
    required this.stressLevel,
  });

  factory RingStressInfo.fromJson(Map<String, dynamic> json) => _$RingStressInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingStressInfoToJson(this);
  
  factory RingStressInfo.fromMap(Map<String, dynamic> map) {
    return RingStressInfo(
      stressLevel: map['stressLevel'] ?? 0,
    );
  }

  String get stressLevelText {
    if (stressLevel < 25) {
      return '低压力';
    } else if (stressLevel < 50) {
      return '中等压力';
    } else if (stressLevel < 75) {
      return '高压力';
    } else {
      return '极高压力';
    }
  }

  @override
  String toString() {
    return 'RingStressInfo{stressLevel=$stressLevel ($stressLevelText)}';
  }
}

/// 训练信息模型
@JsonSerializable()
class RingTrainingInfo {
  final int type;
  final int startTime;
  final int endTime;
  final int validTime;
  final int steps;
  final int distance;
  final int calories;
  final int goalType;
  final int goalValue;
  final List<int> hrList;

  const RingTrainingInfo({
    required this.type,
    required this.startTime,
    required this.endTime,
    required this.validTime,
    required this.steps,
    required this.distance,
    required this.calories,
    required this.goalType,
    required this.goalValue,
    required this.hrList,
  });

  factory RingTrainingInfo.fromJson(Map<String, dynamic> json) => _$RingTrainingInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingTrainingInfoToJson(this);
  
  factory RingTrainingInfo.fromMap(Map<String, dynamic> map) {
    return RingTrainingInfo(
      type: map['type'] ?? 0,
      startTime: map['startTime'] ?? 0,
      endTime: map['endTime'] ?? 0,
      validTime: map['validTime'] ?? 0,
      steps: map['steps'] ?? 0,
      distance: map['distance'] ?? 0,
      calories: map['calories'] ?? 0,
      goalType: map['goalType'] ?? 0,
      goalValue: map['goalValue'] ?? 0,
      hrList: List<int>.from(map['hrList'] ?? []),
    );
  }

  @override
  String toString() {
    return 'RingTrainingInfo{type=$type, startTime=$startTime, endTime=$endTime, validTime=$validTime, steps=$steps, distance=$distance, calories=$calories, goalType=$goalType, goalValue=$goalValue, hrList=${hrList.length} entries}';
  }
}

/// 设备信息模型
@JsonSerializable()
class RingDeviceInfo {
  final int color;
  final int size;
  final int type;

  const RingDeviceInfo({
    required this.color,
    required this.size,
    required this.type,
  });

  factory RingDeviceInfo.fromJson(Map<String, dynamic> json) => _$RingDeviceInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingDeviceInfoToJson(this);
  
  factory RingDeviceInfo.fromMap(Map<String, dynamic> map) {
    return RingDeviceInfo(
      color: map['color'] ?? 0,
      size: map['size'] ?? 0,
      type: map['type'] ?? 0,
    );
  }

  @override
  String toString() {
    return 'RingDeviceInfo{color=$color, size=$size, type=$type}';
  }
}

/// 数据状态枚举
enum DataState {
  collecting,
  completed,
  error,
}

/// 睡眠类型枚举
enum SleepChronotype {
  earlyBird,
  nightOwl,
  normal,
}

/// 睡眠类型信息模型
@JsonSerializable()
class RingSleepChronotypeInfo {
  final DataState state;
  final SleepChronotype? sleepChronotype;
  final bool highConfidence;
  final int bedtime;

  const RingSleepChronotypeInfo({
    required this.state,
    this.sleepChronotype,
    required this.highConfidence,
    required this.bedtime,
  });

  factory RingSleepChronotypeInfo.fromJson(Map<String, dynamic> json) => _$RingSleepChronotypeInfoFromJson(json);
  
  Map<String, dynamic> toJson() => _$RingSleepChronotypeInfoToJson(this);
  
  factory RingSleepChronotypeInfo.fromMap(Map<String, dynamic> map) {
    DataState dataState = DataState.collecting;
    if (map['state'] != null) {
      switch (map['state']) {
        case 'COLLECTING':
          dataState = DataState.collecting;
          break;
        case 'COMPLETED':
          dataState = DataState.completed;
          break;
        case 'ERROR':
          dataState = DataState.error;
          break;
      }
    }

    SleepChronotype? chronotype;
    if (map['sleepChronotype'] != null) {
      switch (map['sleepChronotype']) {
        case 'EARLY_BIRD':
          chronotype = SleepChronotype.earlyBird;
          break;
        case 'NIGHT_OWL':
          chronotype = SleepChronotype.nightOwl;
          break;
        case 'NORMAL':
          chronotype = SleepChronotype.normal;
          break;
      }
    }

    return RingSleepChronotypeInfo(
      state: dataState,
      sleepChronotype: chronotype,
      highConfidence: map['highConfidence'] ?? false,
      bedtime: map['bedtime'] ?? 0,
    );
  }

  String get stateText {
    switch (state) {
      case DataState.collecting:
        return '收集中';
      case DataState.completed:
        return '已完成';
      case DataState.error:
        return '错误';
    }
  }

  String get chronotypeText {
    switch (sleepChronotype) {
      case SleepChronotype.earlyBird:
        return '早鸟型';
      case SleepChronotype.nightOwl:
        return '夜猫型';
      case SleepChronotype.normal:
        return '正常型';
      case null:
        return '未知';
    }
  }

  @override
  String toString() {
    return 'RingSleepChronotypeInfo{state=$stateText, sleepChronotype=$chronotypeText, highConfidence=$highConfidence, bedtime=$bedtime}';
  }
}
